package com.example.service.impl.image;


import com.aliyun.oss.OSS;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.config.AliyunOSSProperties;
import com.example.entity.dto.Account;
import com.example.entity.dto.StoreImage;
import com.example.mapper.AccountMapper;
import com.example.mapper.ImageStoreMapper;
import com.example.service.ImageService;
import com.example.utils.FlowUtils;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import io.minio.errors.*;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import org.apache.commons.compress.utils.IOUtils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * @author lbwxxc
 * @date 2025/4/15 21:45
 * @description: 阿里云OSS
 */
@Slf4j
@Component
@ConditionalOnExpression(value = "#{'ali'.equals(environment.getProperty('spring.image.oss.type'))}")
public class AliyunImageServiceImpl extends ServiceImpl<ImageStoreMapper, StoreImage> implements ImageService {

    @Resource
    AccountMapper accountMapper;
    @Resource
    FlowUtils flowUtils;
    @Resource
    private AliyunOSSProperties aliyunOSSProperties;
    @Resource
    private OSS ossClient;
    private SimpleDateFormat format =  new SimpleDateFormat("yyyyMMdd");

    @Override
    public String uploadAvatar(MultipartFile file, int id) throws Exception {
        String originalFilename = file.getOriginalFilename();
        String key = UUID.randomUUID().toString().replaceAll("-", "");
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        String newFilename = String.format("%s%s", key, suffix);
        Date date = new Date();
        String objectName = "/cache/" + format.format(date) + "/" + newFilename;
        ossClient.putObject("school-forum-lbwxxc", objectName, new ByteArrayInputStream(file.getBytes()));
        String avatar = accountMapper.selectById(id).getAvatar();
        this.deleteOldAvatar(avatar);

        if (accountMapper.update(null, Wrappers.<Account>update().eq("id", id).set("avatar", objectName)) == 0) {
            return null;
        } else {
            log.info("用户上传了头像" + file.getOriginalFilename());
            return objectName;
        }
    }

    @Override
    public String uploadImage(MultipartFile file, int id) throws IOException {
        String originalFilename = file.getOriginalFilename();
        String key = UUID.randomUUID().toString().replaceAll("-", "");
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        String newFilename = String.format("%s%s", key, suffix);
        Date date = new Date();
        String objectName = "/cache/" + format.format(date) + "/" + newFilename;
        ossClient.putObject("school-forum-lbwxxc", objectName, new ByteArrayInputStream(file.getBytes()));

        if (this.save(new StoreImage(id, objectName, date))) {
            return objectName;
        } else {
            return null;
        }
    }

    @Override
    public void fetchImageFromMinio(OutputStream stream, String image) throws Exception {
        InputStream objectContent = ossClient.getObject("school-forum-lbwxxc", image).getObjectContent();
        IOUtils.copy(objectContent, stream);
    }

    private void deleteOldAvatar(String avatar) throws Exception {
        if (avatar == null || avatar.isEmpty()) {
            return;
        }
        RemoveObjectArgs remove = RemoveObjectArgs.builder()
                .bucket("study")
                .object(avatar)
                .build();
        ossClient.restoreObject("school-forum-lbwxxc", avatar);
        log.info("删除了旧头像:" + avatar);
    }
}
